//============================================================================
// UsbLinkPacket.cs
//
// Copyright (c) 2005-2006 U.S. TrailMaps, LLC
// THIS MATERIAL IS CONFIDENTIAL AND PROPRIETARY TO U.S. TRAILMAPS AND
// MAY NOT BE REPRODUCED, PUBLISHED OR DISCLOSED TO OTHERS WITHOUT COMPANY
// AUTHORIZATION.
//
// This work is derived from Waymex GPS Library for .Net version 2.7.9 source.
// Portions copyright (c) 2004-2005 Waymex IT Ltd
//============================================================================

using System;

namespace Waymex.Gps.Garmin.Usb
{
	internal enum UsbPacketType : byte
	{
		UsbProtocolLayer = 0,
		ApplicationLayer = 20
	}

	internal class UsbLinkPacket : BytePacket
	{
		public const int HeaderSize = 12;

		public UsbLinkPacket() : base(HeaderSize)
		{
		}

		public UsbLinkPacket(int capacity) : base(capacity)
		{
		}

		public UsbLinkPacket(UsbPacketType packetType, byte packetId) : base(HeaderSize)
		{
			SetLengthAndClear(HeaderSize);
			PacketType = packetType;
			PacketId = packetId;
		}

		public UsbLinkPacket(ApplicationPacket packet) : base(HeaderSize + packet.PacketData.Length)
		{
			SetLengthAndClear(HeaderSize + packet.PacketData.Length);
			PacketType = UsbPacketType.ApplicationLayer;
			PacketId = packet.PacketId;
			DataSize = packet.PacketData.Length;
			if (packet.PacketData.Length > 0)
				base.SetBytes(HeaderSize, packet.PacketData);
		}

		public UsbPacketType PacketType
		{
			get
			{
				return (UsbPacketType)base[0];
			}
			set
			{
				base[0] = (byte)value;
			}
		}

		public ushort PacketId
		{
			get
			{
				return base.GetUInt16(4);
			}
			set
			{
				base.SetUInt16(4, value);
			}
		}

		public int DataSize
		{
			get
			{
				return base.GetInt32(8);
			}
			set
			{
				base.SetInt32(8, value);
			}
		}

		public byte[] DataToArray()
		{
			if (DataSize == 0)
				return null;
			else
				return base.GetBytes(HeaderSize, DataSize);
		}

		public uint GetDataUInt32(int index)
		{
			return base.GetUInt32(HeaderSize + index);
		}

		public bool IsValid
		{
			get
			{
				return (Length >= HeaderSize &&
					(PacketType == UsbPacketType.UsbProtocolLayer || PacketType == UsbPacketType.ApplicationLayer) &&
					Length == HeaderSize + DataSize);
			}
		}

		public bool IsValidIncomplete
		{
			get
			{
				if (Length >= 1 && (PacketType != UsbPacketType.UsbProtocolLayer && PacketType != UsbPacketType.ApplicationLayer))
					return false;
				if (Length >= 12 && (Length >= HeaderSize + DataSize))
					return false;
				return true;
			}
		}
	}
}
